﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Avalonia.Controls;
using DynamicData;
using MusicFluent.Models;
using NetEasyMusic.Lib.Data;
using NetEasyMusic.Lib.Models;

namespace MusicFluent.ViewModels;

public class MainWindowViewModel : ViewModelBase
{
    public MainWindowViewModel(string cookie)
    {
        Player = new VlcModel();
        Player.PosFlush += f => Pos = f;
        Player.Done += Next;
        Cookie = cookie;
    }

    public void PosChange(float value)
    {
        Player.PosChange(value);
    }

    #region BasicInfo

    private string Cookie { get; }

    public ObservableCollection<string> Levels { get; set; } = new(Music.Level.Keys);
    private string _level = "标准";

    public string Level
    {
        get => _level;
        set => SetField(ref _level, value);
    }

    #endregion

    #region Playing

    public SongModel? PlayingMusic { get; set; }

    private float _pos;

    public float Pos
    {
        get => _pos;
        private set => SetField(ref _pos, value);
    }

    private string _playState = "Play";

    public string PlayState
    {
        get => _playState;
        set
        {
            SetField(ref _playState, value);
            if (value == "Pause")
                Player.Pause();
            else
                Player.Play();
        }
    }

    #endregion

    #region PlayerSetting

    private string _mode = "List";

    public string Mode
    {
        get => _mode;
        set => SetField(ref _mode, value);
    }

    public List<SongModel> List { get; set; } = [];

    /// <summary>
    ///     Mode change : Single -> Single Loop -> List -> Random -> Single
    /// </summary>
    public void ModeChange()
    {
        switch (Mode)
        {
            case "Single":
                Mode = "Single Loop";
                return;
            case "Single Loop":
                Mode = "List";
                return;
            case "List":
                Mode = "Random";
                return;
            case "Random":
                Mode = "Single";
                break;
        }
    }

    private VlcModel Player { get; }

    #endregion

    #region Func

    public void Next()
    {
        if (PlayingMusic is null) return;
        var Index = List.FindIndex(x => x.Id == PlayingMusic.Id);
        if (Index < 0) return;
        switch (Mode)
        {
            case "Single" or "":
                return;
            case "Single Loop":
                break;
            case "List":
                Index++;
                if (Index >= List.Count)
                    Index = 0;
                break;
            case "Random":
                var random = new Random();
                var ran = random.Next(0, List.Count - 1);
                Index = ran == Index ? Index + 1 : ran;
                if (Index >= List.Count || Index <= 0)
                    Index = 0;
                break;
        }

        PlayingMusic = List[Index];
        PlayChange(PlayingMusic.Id);
        Pos = 0;
    }

    public void Play()
    {
        PlayState = PlayState == "Play" ? "Pause" : "Play";
    }

    public async void PlayChange(string id)
    {
        if (PlayState == "Play")
        {
            Pos = 0;
            PlayState = "Pause";
            Player.Stop();
        }

        using var music = new Music(Cookie);
        var url = await music.GetUrl(id, Music.Level[Level]);
        Player.Play(new Uri(url));
        PlayState = "Play";
    }

    public void Add(ItemCollection? collection)
    {
        if (collection is null) return;
        var models = collection.OfType<SongModel>();
        List.Clear();
        List.Add(models);
    }

    public void Add(IEnumerable<SongModel> models)
    {
        List.Clear();
        List.Add(models);
    }

    public void Add(SongModel model)
    {
        List.Add(model);
    }

    #endregion
}